/*******************************************************************************
*
*
*******************************************************************************/
#include "bsp.h"
#include "systask.h"

#define APP_TIM        TIMER3
#define app_timer_isr  TMR3_IRQHandler
#define APP_TIM_IRQn   TMR3_IRQn
#define APP_TIM_PERIOD 1000

/******************************************************************************
*	                            function
*******************************************************************************/
uint32_t app_tick_init (uint32_t TickPriority);
void app_tick_suspend(void);
void app_tick_resume(void);
uint32_t app_tick_get(void);
uint32_t app_tick_us_get(void);
void app_tick_isr(void);

/******************************************************************************
*	                            var
*******************************************************************************/
volatile static uint32_t hal_tick_cnt = 0;
static vtask_vector_type task_list;

/*******************************************************************************
* @brief  app_tick_init
* \param[in] none
* \retval: none
*******************************************************************************/
uint32_t app_tick_init (uint32_t TickPriority)
{
    uint32_t u32Cmpr = 0UL, u32Prescale = 0UL;
    uint32_t u32Clk = TIMER_GetModuleClock(APP_TIM);

	// 计算分频和比较值
	u32Prescale = u32Clk / 1000000 - 1;
	u32Cmpr = 1000 - 1;
	
	// 设置寄存器
    APP_TIM->CTL = TIMER_PERIODIC_MODE | u32Prescale;
    APP_TIM->CMP = u32Cmpr;

	// 开中断
	TIMER_EnableInt(APP_TIM);
	
	nvic_irq_set(APP_TIM_IRQn, 3, 1);
	
	// 初始化任务列表
    vtask_list_init(&task_list, 0);
    
	// 开始
	TIMER_Start(APP_TIM);
	
	return 0;
}

/*******************************************************************************
* @brief  app_tick_suspend
* \param[in] none
* \retval: none
*******************************************************************************/
void app_tick_suspend(void)
{
	TIMER_DisableInt(APP_TIM);
}

/*******************************************************************************
* @brief  app_tick_resume
* \param[in] none
* \retval: none
*******************************************************************************/
void app_tick_resume(void)
{
	TIMER_EnableInt(APP_TIM);
}

/*******************************************************************************
* @brief  app_tick_get
* \param[in] none
* \retval: none
*******************************************************************************/
uint32_t app_tick_get(void)
{
    return hal_tick_cnt;
}

/*******************************************************************************
* @brief  app_tick_us_get
* \param[in] none
* \retval: none
*******************************************************************************/
uint32_t app_tick_us_get(void)
{
    uint32_t time_us;
	
    intx_alloc();
    
    intx_disable();
    
    time_us = hal_tick_cnt * APP_TIM_PERIOD;
	
    time_us += APP_TIM->CNT & 0x00FFFFFF;
    
    intx_enable();
    
    return time_us;
}


/*******************************************************************************
* @brief  app_tick_isr
* \param[in] none
* \retval: none
*******************************************************************************/
#include "nand_w25n.h"
extern uint16_t nand_u_tick;
void app_timer_isr(void)
{
    TIMER_ClearIntFlag(APP_TIM);
	
    spi_nand_info.tick++;
	
    sys_st.ticks++;
	
    hal_tick_cnt++;
    
    vtask_list_run_once(&task_list);
}

/*******************************************************************************
* @brief  app timer task add
* \param[in] none
* \retval: none
*******************************************************************************/
void app_timer_task_add(void (*task)(void))
{
	vtask_list_add(&task_list, task);
}

/*******************************************************************************
* @brief  app timer task del
* \param[in] none
* \retval: none
*******************************************************************************/
void app_timer_task_del(void (*task)(void))
{
	vtask_list_del(&task_list, task);
}

